package net.yxsoft.kit;

import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import net.yxsoft.resource.RetRes;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.ArrayUtils;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * 非对称加解密
 */
public class RSAKit {

  public static void main(String[] args) {

    Ret ret = RSAKit.generatorRSA();

    System.out.println("私钥:" + ret.get(RetRes.PRIVATE_KEY));
    System.out.println("公钥:" + ret.get(RetRes.PUBLIC_KEY));

   String mw= RSAKit.x509EncodedKeySpec("MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ9jZQqSLct7H+v9+14nTzMJOtZaYL7obhRxWyQ+ywtJfJs34/CUif+cXbW5FaGhG1kyj/gd3tpvOJlYppb0xr0CAwEAAQ==", " |80后|testdb|testdb|无| | | | | |156| | | | | | | | | |".replaceAll(" ",""));
    System.out.println(mw);
    String jm= RSAKit.pkcs8EncodedKeySpec("MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAn2NlCpIty3sf6/37XidPMwk61lpgvuhuFHFbJD7LC0l8mzfj8JSJ/5xdtbkVoaEbWTKP+B3e2m84mVimlvTGvQIDAQABAkAB69rN89ElgMhzuc4L5oFn5haVeuVrp7Wb/XnRyAf+jNFAiS51pWQtEmToVZp5ElKQewhO2YY4PrSZO7f6SstpAiEA+CC01p/VRxfjJKuxfjncYpmXEXcHFucrsAbFdeWe6EcCIQCkcfIz7u6hYLvSZzDO7F8WdoCqnQL90UNCmPQDUnZe2wIgag04nb8k3kUEbYkAzO2YF4CEBA/2tMBLeOn7/b8N40MCIHeCrEBb/CdiUv4Vqp4noO+FTfswwvTN+bDT0jr72jUTAiBuHQF1oT08xFsbKnTdAXRwHQpA8kkM33vVJhRWsgT6Hg==", mw);
    System.out.println(jm);
  }

  public static Ret generatorRSA(){

    //初始化密钥
    KeyPairGenerator keyPairGenerator = null;
    try {
      keyPairGenerator = KeyPairGenerator.getInstance("RSA");
      keyPairGenerator.initialize(512);
      KeyPair keyPair = keyPairGenerator.generateKeyPair();
      RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
      RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();

      return Ret.ok(RetRes.PUBLIC_KEY, Base64.encodeBase64String(rsaPublicKey.getEncoded())).set(RetRes.PRIVATE_KEY,Base64.encodeBase64String(rsaPrivateKey.getEncoded()));

    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    }

    return Ret.fail();
  }

  /**
   * 私钥加密、公钥解密 ---- 加密
   * @param key  私钥
   * @param content  要加密的内文
   * @return
   */
  public static String pkcs8EncodedKey(String key, String content){

    if(StrKit.isBlank(key) || StrKit.isBlank(content)){

      return null;
    }

    try {

      PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(key));
      KeyFactory keyFactory = KeyFactory.getInstance("RSA");
      PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
      Cipher cipher = Cipher.getInstance("RSA");
      cipher.init(Cipher.ENCRYPT_MODE, privateKey);
      byte[] result = cipher.doFinal(content.getBytes());

      return Base64.encodeBase64String(result);

    }catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (InvalidKeyException e) {
      e.printStackTrace();
    } catch (NoSuchPaddingException e) {
      e.printStackTrace();
    } catch (BadPaddingException e) {
      e.printStackTrace();
    } catch (InvalidKeySpecException e) {
      e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
      e.printStackTrace();
    }

    return null;
  }


  /**
   * 私钥加密、公钥解密 ---- 解密
   * @param key 公钥
   * @param ciphertext  密文
   * @return
   */
  public static String x509EncodedKey(String key, String ciphertext){

    if(StrKit.isBlank(key) || StrKit.isBlank(ciphertext)){

      return null;
    }

    try {

      X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(key));
      KeyFactory keyFactory = KeyFactory.getInstance("RSA");
      PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
      Cipher cipher = Cipher.getInstance("RSA");
      cipher.init(Cipher.DECRYPT_MODE, publicKey);
      byte[] result = cipher.doFinal(Base64.decodeBase64(ciphertext));

      return new String(result);
    }catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (InvalidKeySpecException e) {
      e.printStackTrace();
    } catch (NoSuchPaddingException e) {
      e.printStackTrace();
    } catch (BadPaddingException e) {
      e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
      e.printStackTrace();
    } catch (InvalidKeyException e) {
      e.printStackTrace();
    }

    return null;
  }

  /**
   * 公钥加密，私钥解密 ---- 加密
   * @param key  公钥
   * @param content  要加密的内容
   * @return
   */
  public static String x509EncodedKeySpec(String key, String content){

    if(StrKit.isBlank(key) || StrKit.isBlank(content)){

      return null;
    }

    try {

      X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(key));
      KeyFactory keyFactory = KeyFactory.getInstance("RSA");
      PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
      Cipher cipher = Cipher.getInstance("RSA");
      cipher.init(Cipher.ENCRYPT_MODE, publicKey);

      StringBuilder sb = new StringBuilder();
      byte[] dataReturn = new byte[0];
      byte[] data = content.getBytes();
      for (int i = 0; i < data.length; i += 50) {
        byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i,
                i + 50));
        dataReturn = ArrayUtils.addAll(dataReturn, doFinal);
        sb.append(new String(doFinal));
      }

      //byte[] result = cipher.doFinal(content.getBytes());

      return Base64.encodeBase64String(dataReturn);
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (InvalidKeyException e) {
      e.printStackTrace();
    } catch (NoSuchPaddingException e) {
      e.printStackTrace();
    } catch (BadPaddingException e) {
      e.printStackTrace();
    } catch (InvalidKeySpecException e) {
      e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
      e.printStackTrace();
    }
    return null;
  }

  /**
   * 公钥加密，私钥解密 ---- 解密
   * @param key  私钥
   * @param ciphertext  密文
   * @return
   */
  public static String pkcs8EncodedKeySpec(String key, String ciphertext){

    if(StrKit.isBlank(key) || StrKit.isBlank(ciphertext)){

      return null;
    }

    try {

      PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(key));
      KeyFactory keyFactory = KeyFactory.getInstance("RSA");
      PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
      Cipher cipher = Cipher.getInstance("RSA");
      cipher.init(Cipher.DECRYPT_MODE, privateKey);


      StringBuilder sb = new StringBuilder();
      String dataReturn;
      byte [] data =Base64.decodeBase64(ciphertext);
    for (int i = 0; i < data.length; i += 64) {
        byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i,
                i + 64));
        sb.append(new String(doFinal));
      }

      //byte[] result = cipher.doFinal(Base64.decodeBase64(ciphertext));
      dataReturn = sb.toString();


      return new String(dataReturn);
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (InvalidKeyException e) {
      e.printStackTrace();
    } catch (NoSuchPaddingException e) {
      e.printStackTrace();
    } catch (BadPaddingException e) {
      e.printStackTrace();
    } catch (InvalidKeySpecException e) {
      e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
      e.printStackTrace();
    }

    return null;
  }



}
